home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk10.zip / ZMALLOC.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  5KB  |  177 lines

  1.  
  2. /********************************************
  3. zmalloc.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13. /*$Log:    zmalloc.c,v $
  14.  * Revision 3.4.1.1  91/09/14  17:24:31  brennan
  15.  * VERSION 1.0
  16.  * 
  17.  * Revision 3.4  91/08/13  06:52:19  brennan
  18.  * VERSION .9994
  19.  * 
  20.  * Revision 3.3  91/06/28  04:17:47  brennan
  21.  * VERSION 0.999
  22.  * 
  23.  * Revision 3.2  91/06/26  05:57:48  brennan
  24.  * fixed alignment bug , only showed on some machines, V9981
  25.  * 
  26.  * Revision 3.1  91/06/07  10:28:30  brennan
  27.  * VERSION 0.995
  28.  * 
  29.  * Revision 2.7  91/06/05  11:22:37  brennan
  30.  * changed stupid computation of blocks
  31.  * 
  32.  * Revision 2.6  91/06/05  07:20:44  brennan
  33.  * better error messages when regular expression compiles fail
  34.  * 
  35.  * Revision 2.5  91/06/04  09:12:00  brennan
  36.  * added some ptr casts
  37.  * 
  38.  * Revision 2.4  91/06/04  06:50:34  brennan
  39.  * use parser table memory in zmalloc (if using byacc)
  40.  * 
  41.  * Revision 2.3  91/06/03  07:39:52  brennan
  42.  * fixed bug that only shows up if nearly out of memory
  43.  * this bug was found by Carl Mascott
  44.  * 
  45.  * Revision 2.2  91/04/09  12:39:45  brennan
  46.  * added static to funct decls to satisfy STARDENT compiler
  47.  * 
  48.  * Revision 2.1  91/04/08  08:24:17  brennan
  49.  * VERSION 0.97
  50.  * 
  51. */
  52.  
  53. /*  zmalloc.c  */
  54. #include  "mawk.h"
  55. #include  "zmalloc.h"
  56.  
  57. void PROTO( mawk_exit, (int) ) ;
  58.  
  59. extern  struct yacc_mem  *yacc_memp ;
  60.  
  61. /*
  62.   zmalloc() gets mem from malloc() in CHUNKS of 2048 bytes
  63.   and cuts these blocks into smaller pieces that are multiples
  64.   of eight bytes.  When a piece is returned via zfree(), it goes
  65.   on a linked linear list indexed by its size.  The lists are
  66.   an array, pool[].
  67.  
  68.   E.g., if you ask for 22 bytes with p = zmalloc(22), you actually get
  69.   a piece of size 24.  When you free it with zfree(p,22) , it is added
  70.   to the list at pool[2].
  71. */
  72.  
  73. #define ZBLOCKSZ    8    
  74. #define ZSHIFT      3
  75. #define POOLSZ      16
  76.  
  77. #define  CHUNK          256    
  78.         /* number of blocks to get from malloc */
  79.  
  80. static PTR  PROTO( emalloc, (unsigned) ) ;
  81. void PROTO( errmsg, (int , char *, ...) ) ;
  82.  
  83. static PTR emalloc(size)
  84.   unsigned size ;
  85. { PTR p ;
  86.   static char out[] = "out of memory" ;
  87.  
  88.   if( !(p = (PTR) malloc(SIZE_T(size))) )
  89.     if ( mawk_state == EXECUTION ) rt_error(out) ;
  90.     else /* I don't think this will ever happen */
  91.     { compile_error(out) ; mawk_exit(1) ; }
  92.   return p ;
  93. }
  94.  
  95.  
  96. typedef  union  zblock {
  97. char dummy[ZBLOCKSZ] ;
  98. union zblock *link ;
  99. }  ZBLOCK  ;
  100.  
  101. /* ZBLOCKS of sizes 1, 2, ... 16
  102.    which is bytes of sizes 8, 16, ... , 128
  103.    are stored on the linked linear lists in
  104.    pool[0], pool[1], ... , pool[15]
  105. */
  106.  
  107. static  ZBLOCK  *pool[POOLSZ] ;
  108.  
  109. PTR   zmalloc( size )
  110.   unsigned size ;
  111. { register unsigned blocks ;
  112.   register ZBLOCK *p ;
  113.   static  unsigned amt_avail ;
  114.   static  ZBLOCK  *avail ;
  115.  
  116.   if ( size > POOLSZ * ZBLOCKSZ )  return emalloc(size) ;
  117.  
  118.   blocks = (size + (ZBLOCKSZ-1)) >> ZSHIFT ;
  119.  
  120.   if ( p = pool[blocks-1] )
  121.   { pool[blocks-1] = p->link ; return (PTR) p ; }
  122.  
  123.   if ( blocks > amt_avail )
  124.   { if ( amt_avail ) /* free avail */
  125.     { avail->link = pool[--amt_avail] ; pool[amt_avail] = avail ; }
  126.  
  127.     /* use parser tables first */
  128.     if ( yacc_memp->zblocks >= blocks )
  129.     { avail = (ZBLOCK *) yacc_memp->mem ;
  130.       amt_avail = yacc_memp++ -> zblocks ;
  131.       /* make sure its -- aligned */
  132.       if ( (int) avail & 7 )
  133.       { avail = (ZBLOCK*)((char *)avail + 8 - ((int)avail&7)) ;
  134.     amt_avail-- ;
  135.       }
  136.     }
  137.     else
  138.     if ( !(avail = (ZBLOCK *) malloc(SIZE_T(CHUNK*ZBLOCKSZ))) )
  139.     { /* if we get here, almost out of memory */
  140.         amt_avail = 0 ;   
  141.     return  emalloc(blocks << ZSHIFT) ;
  142.     }
  143.     else  amt_avail = CHUNK ;
  144.   }
  145.   
  146.   /* get p from the avail pile */
  147.   p = avail ; avail += blocks ; amt_avail -= blocks ; 
  148.   return (PTR) p ;
  149. }
  150.  
  151. void  zfree( p, size)
  152.   register PTR p ;  unsigned size ;
  153. { register int index ; ;
  154.  
  155.   if ( size > POOLSZ * ZBLOCKSZ )  free(p) ;
  156.   else
  157.   {
  158.     index  = ((size + (ZBLOCKSZ-1))>>ZSHIFT) - 1;
  159.     ((ZBLOCK *) p)->link = pool[index] ;
  160.     pool[index] = (ZBLOCK *) p ;
  161.   }
  162. }
  163.  
  164. PTR  zrealloc( p, old_size, new_size )
  165.   register PTR  p ;
  166.   unsigned old_size, new_size ;
  167. { register PTR q ;
  168.  
  169.   (void) memcpy(q = zmalloc(new_size), p, 
  170.                 SIZE_T(old_size < new_size ? old_size : new_size)) ;
  171.  
  172.   zfree(p, old_size) ;
  173.   return q ;
  174. }
  175.  
  176.  
  177.